/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.antilia.infomaresme.pages.edit;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.util.lang.Bytes;

import com.antilia.infomaresme.InfomaresmeApplication;
import com.antilia.infomaresme.data.dataobjects.ImageInfo;
import com.antilia.infomaresme.data.dataobjects.Item;
import com.antilia.infomaresme.data.services.IImageService;
import com.antilia.infomaresme.pages.RoundSubmitLinkPanel;
import com.antilia.infomaresme.provider.ImageInfosDataProvider;
import com.antilia.infomaresme.resources.InfoModalWindow;

/**
 * Demos ajax handling of a multipart form
 * 
 * @author igor.vaynberg
 */
public class FileUploadPanel extends org.apache.wicket.markup.html.panel.Panel
{
	private static final long serialVersionUID = 1L;
	
	private FileUploadField file;

	private ImageInfosDataProvider  dataProvider;
	
	private AjaxFallbackDefaultDataTable<ImageInfo>	files;
	
	private ImageInfo imageInfo;
	
	private Form<?> form;
	
	private List<FileUpload> fileUploads = new ArrayList<FileUpload>();
	
	private ModalWindow  modal;
	/**
	 * Constructor
	 */
	public FileUploadPanel(String id, final IModel<Item> model) {
		super(id, model);
		// create a feedback panel
		final Component feedback = new FeedbackPanel("feedback").setOutputMarkupPlaceholderTag(true);
		add(feedback);

		modal = new InfoModalWindow("modal");
		add(modal);
		
		imageInfo = new ImageInfo();
		imageInfo.setItem(model.getObject());
		
		// create the form
		form = new Form<ImageInfo>("form", new CompoundPropertyModel<ImageInfo>(imageInfo));
		form.setOutputMarkupId(true);
		form.setMaxSize(Bytes.megabytes(2));
		add(form);

		// create a textfield to demo non-file content
		form.add(new TextField<String>("title"));

		// create the file upload field
		form.add(file = new FileUploadField("file", new PropertyModel<List<FileUpload>>(this, "fileUploads")));

		// create the ajax button used to submit the form
		form.add(new RoundSubmitLinkPanel("submitFile", new ResourceModel("actions.addImage"))
		{
			private static final long serialVersionUID = 1L;

			@Override
			protected void onSubmit(AjaxRequestTarget target, Form<?> form)
			{
				// ajax-update the feedback panel
				target.add(feedback);
				FileUpload upload = file.getFileUpload();
				if (upload == null)
				{
					info("No file uploaded");
				}
				else
				{
					String fileName = upload.getClientFileName();
					if(AllowedImageFiles.isAllowed(fileName)){
						imageInfo.setBlobId(upload.getClientFileName());
						imageInfo.setContentType(upload.getContentType());
						imageInfo.setCreationDate(new Date());
						imageInfo.setSize(upload.getSize());
						try {
							InfomaresmeApplication.getQAApplication().getImageInfosDao().save(imageInfo);
							getiImageService().storeImage(imageInfo, model.getObject(), upload.getBytes());
							
							imageInfo = new ImageInfo();
							imageInfo.setItem(model.getObject());
							if(AjaxRequestTarget.get() != null) {
								AjaxRequestTarget.get().add(form);
								AjaxRequestTarget.get().add(files);
							}
						} catch (org.hibernate.exception.ConstraintViolationException e) {
							error("File " + upload.getClientFileName()+ " already exits!");
						}						
					} else {
						//it is no a valid file
						//TODO read from resources.
						error("File " + upload.getClientFileName()+ " is not a valid image");
					}
				}
			}

			@Override
			protected void onError(AjaxRequestTarget target, Form<?> form)
			{
				// update feedback to display errors
				target.add(feedback);
			}

		});
		List<IColumn<ImageInfo>> columns = new ArrayList<IColumn<ImageInfo>>();		
		columns.add(new PropertyColumn<ImageInfo>(Model.of(""), null , "price") {
			
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(
					org.apache.wicket.markup.repeater.Item<ICellPopulator<ImageInfo>> item,
					String componentId, final IModel<ImageInfo> rowModel) {
				item.add(new DetailsFileUploadLinkPanel(componentId, rowModel) {
					
					private static final long serialVersionUID = 1L;

					

					@Override
					public void onSee(AjaxRequestTarget target,
							IModel<ImageInfo> model1) {
						modal.setInitialWidth(800);
						modal.setInitialHeight(700);
						modal.setTitle(new ResourceModel("itemDetails"));
						modal.setContent(new ShowImagePanel(modal.getContentId(),model1, model));
						modal.show(target);
					}
					
					@Override
					public void onDelete(AjaxRequestTarget target,
							final IModel<ImageInfo> model1) {
						modal.setInitialWidth(350);
						modal.setInitialHeight(150);
						modal.setTitle(new ResourceModel("itemDetails"));
						modal.setContent(new ConfirmationPanel(modal.getContentId(),  Model.of("Delete image?") ) {
							
							private static final long serialVersionUID = 1L;

							@Override
							public void onOk(AjaxRequestTarget target) {
								try {
									InfomaresmeApplication.getQAApplication().getImageInfosDao().delete(rowModel.getObject());
									getiImageService().deleteImage(model1.getObject(), model.getObject());
								} catch(Exception e) {
									// waht to do.
								}
								modal.close(target);
								target.add(files);
							}
							
							@Override
							public void onCancel(AjaxRequestTarget target) {							
								// do nothing
								modal.close(target);
							}
						});
						modal.show(target);
					}
				});
			}
		});
		columns.add(new PropertyColumn<ImageInfo>(new ResourceModel("imageInfo.blobId"), null, "blobId"));
		columns.add(new PropertyColumn<ImageInfo>(new ResourceModel("imageInfo.title"), null, "title"));
		columns.add(new PropertyColumn<ImageInfo>(new ResourceModel("imageInfo.creationDate"), null, "title"));
		
		
		dataProvider = new ImageInfosDataProvider() {
			
			private static final long serialVersionUID = 1L;

			@Override
			public Item getItem() {
				return model.getObject();
			}
		};
		files = new AjaxFallbackDefaultDataTable<ImageInfo>("files", columns, dataProvider, 5);
		files.setOutputMarkupId(true);
		add(files);
	}

	public IImageService getiImageService() {
		return InfomaresmeApplication.getQAApplication().getImageService();
	}

	public FileUploadField getFile() {
		return file;
	}

	public void setFile(FileUploadField file) {
		this.file = file;
	}

	public List<FileUpload> getFileUploads() {
		return fileUploads;
	}

	public void setFileUploads(List<FileUpload> fileUploads) {
		this.fileUploads = fileUploads;
	}
}
